/*****************************************************************************
 *  ENTROPY - emerging network to reduce orwellian potency yield
 *
 *  Copyright (C) 2002 Juergen Buchmueller <pullmoll@stop1984.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software Foundation,
 *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 *	$Id: crypt0.c,v 1.2 2005/07/12 23:12:28 pullmoll Exp $
 *****************************************************************************/
#include "crypt.h"
#include "memalloc.h"
#include "logger.h"

#define	CRYPT0_MAGIC	(('N'<<0)|('U'<<8)|('L'<<16)|('L'<<24))

typedef struct crypt0_s {
	uint64_t encrypt_count;
	uint64_t decrypt_count;
	uint32_t magic;
}	crypt0_t;

/***********************************************************************
 *  crypto()
 ***********************************************************************/
int crypt0_crypto(void)
{
	FUN("crypt0_crypto");

	/* no initialization required */

	return 0;
}

/***********************************************************************
 *  init()
 ***********************************************************************/
int crypt0_init(void **pptr, int init, void *data, size_t size)
{
	crypt0_t *c;
	FUN("crypt0_init");

	if (NULL == pptr) {
		LOGS(L_CRYPTO,L_ERROR,("pptr is NULL\n"));
		errno = EINVAL;
		return -1;
	}
	if (0 != init) {
		LOGS(L_CRYPTO,L_ERROR,("init is not 0\n"));
		errno = EINVAL;
		return -1;
	}
	c = (crypt0_t *)xcalloc(sizeof(crypt0_t), 1);
	*pptr = c;

	c->magic = CRYPT0_MAGIC;

	(void)data;
	(void)size;

	return 0;
}

/***********************************************************************
 *  exit()
 ***********************************************************************/
int crypt0_exit(void *ptr)
{
	crypt0_t *c = ptr;
	FUN("crypt0_exit");

	if (NULL == ptr) {
		LOGS(L_CRYPTO,L_ERROR,("pptr is NULL\n"));
		errno = EINVAL;
		return -1;
	}
	if (CRYPT0_MAGIC != c->magic) {
		LOGS(L_CRYPTO,L_ERROR,("magic is %x (!= %x)\n",
			c->magic, CRYPT0_MAGIC));
		errno = EINVAL;
		return -1;
	}

	memset(c, 0, sizeof(*c));
	xfree(ptr);

	return 0;
}

/***********************************************************************
 *  encrypt_msg()
 ***********************************************************************/
int crypt0_encrypt_msg(void *ptr, void *ciphertext, void *plaintext,
	size_t *outsize, size_t insize)
{
	crypt0_t *c = (crypt0_t *)ptr;
	FUN("crypt0_encrypt_msg");

	if (NULL == ptr) {
		LOGS(L_CRYPTO,L_ERROR,("ptr is NULL\n"));
		errno = EINVAL;
		return -1;
	}
	if (NULL == ciphertext) {
		LOGS(L_CRYPTO,L_ERROR,("ciphertext is NULL\n"));
		errno = EINVAL;
		return -1;
	}
	if (NULL == plaintext) {
		LOGS(L_CRYPTO,L_ERROR,("plaintext is NULL\n"));
		errno = EINVAL;
		return -1;
	}
	if (NULL == outsize) {
		LOGS(L_CRYPTO,L_ERROR,("outsize is NULL\n"));
		errno = EINVAL;
		return -1;
	}
	if (insize > *outsize) {
		LOGS(L_CRYPTO,L_ERROR,("outsize is too small (have %x, want %x)\n",
			(unsigned)*outsize, (unsigned)insize));
		errno = ENOMEM;
		return -1;
	}
	if (CRYPT0_MAGIC != c->magic) {
		LOGS(L_CRYPTO,L_ERROR,("magic is not 0x%x\n",
			CRYPT0_MAGIC));
		errno = EINVAL;
		return -1;
	}
	if (ciphertext != plaintext) {
		memcpy(ciphertext, plaintext, insize);
	}
	c->encrypt_count += insize;

	*outsize = insize;
	return 0;
}

/***********************************************************************
 *  decrypt_msg()
 ***********************************************************************/
int crypt0_decrypt_msg(void *ptr, void *plaintext, void *ciphertext,
	size_t *outsize, size_t insize)
{
	crypt0_t *c = (crypt0_t *)ptr;
	FUN("crypt0_decrypt_msg");

	if (NULL == ptr) {
		LOGS(L_CRYPTO,L_ERROR,("ptr is NULL\n"));
		errno = EINVAL;
		return -1;
	}
	if (NULL == ciphertext) {
		LOGS(L_CRYPTO,L_ERROR,("ciphertext is NULL\n"));
		errno = EINVAL;
		return -1;
	}
	if (NULL == plaintext) {
		LOGS(L_CRYPTO,L_ERROR,("plaintext is NULL\n"));
		errno = EINVAL;
		return -1;
	}
	if (NULL == outsize) {
		LOGS(L_CRYPTO,L_ERROR,("outsize is NULL\n"));
		errno = EINVAL;
		return -1;
	}
	if (insize > *outsize) {
		LOGS(L_CRYPTO,L_ERROR,("outsize is too small (have %x, want %x)\n",
			(unsigned)*outsize, (unsigned)insize));
		errno = ENOMEM;
		return -1;
	}
	if (CRYPT0_MAGIC != c->magic) {
		LOGS(L_CRYPTO,L_ERROR,("magic is not 0x%x\n",
			CRYPT0_MAGIC));
		errno = EINVAL;
		return -1;
	}
	if (ciphertext != plaintext) {
		memcpy(plaintext, ciphertext, insize);
	}
	c->decrypt_count += insize;

	*outsize = insize;
	return 0;
}

